import express from "express";
import { createPageRenderer } from "vite-plugin-ssr";
import { scrawl, redis } from "../utils";
import { LastestPidKey, Weeks } from "../content";

const isProduction = process.env.NODE_ENV === "production";
const root = `${__dirname}/..`;

startServer();

async function startServer() {
  const app = express();

  app.use("/static", express.static("public"));

  let viteDevServer;
  if (isProduction) {
    app.use(express.static(`${root}/dist/client`));
  } else {
    const vite = require("vite");
    viteDevServer = await vite.createServer({
      root,
      server: { middlewareMode: "ssr" },
    });
    app.use(viteDevServer.middlewares);
  }

  const renderPage = createPageRenderer({ viteDevServer, isProduction, root });
  app.get("*", async (req, res, next) => {
    const url = req.originalUrl;
    let pageContextInit: any = {
      url,
    };
    console.log("fetch", url);
    let pids: any = await redis.get(LastestPidKey);
    if (pids) {
      pids = JSON.parse(pids) as string[];
    } else {
      pids = Weeks.map((v) => "latest");
    }
    if (url.includes("post")) {
      const query = req.query as { cid: string; id: string };
      console.log("fetch", query);
      const content = await scrawl(query.cid, query.id);
      if (content.pid && content.isNew) {
        pids[Number(query.cid) - 1] = content.pid;
        redis.set(LastestPidKey, JSON.stringify(pids));
      }
      pageContextInit = {
        ...pageContextInit,
        pageProps: content,
        documentProps: {
          title: content.title,
          stylesheet: content.stylesheet
        },
      };
    } else {
      pageContextInit = {
        ...pageContextInit,
        pageProps: {
          pids,
        },
      };
    }
    const pageContext = await renderPage(pageContextInit);
    const { httpResponse } = pageContext;
    if (!httpResponse) return next();
    const { body, statusCode, contentType } = httpResponse;
    res.status(statusCode).type(contentType).send(body);
  });

  const port = process.env.PORT || 3300;
  app.listen(port);
  console.log(`Server running at http://localhost:${port}`);
}
